<?php
/** UTF-8
 * Concentré Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Concentre
 * @package    Concentre_Archive
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version	   $ID$ r$Rev: 16 $ $Author: alban.lopez $ $Date: 2009-03-28 12:42:00 +0000 (Sat, 28 Mar 2009) $ 
 * @author	   S�bastien Cramattte <scramatte@zensoluciones.com>
 * @author	   Alban Lopez <alban.lopez+archive@gmail.com>
 * @see		   Based on EasyArchive <http://www.phpclasses.org/browse/package/4239.html>
 */


/**
 * @see Concentre_Archive_Abstract
 */
require_once 'Concentre/Archive/Abstract.php';

/**
 * @see Concentre_Archive_Interface
 */
require_once 'Concentre/Archive/Interface.php';


/**
 * @category   Concentre
 * @package    Concentre_Archive
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Concentre_Archive_Zip extends Concentre_Archive_Abstract
{

    /**
     * Constructor
     *
     * @throws Concentre_Archive_Exception
     * @return void
     */
	public function __construct() {
		if (!extension_loaded('zip')) {
			throw new Concentre_Archive_Exception('Zip extension unavailable');
		}
	}

    /**
     * Make archive
     *   
     * @param  DirectoryIterator $src
     * @param  string $dest
     * @return binary|string|boolean
     */	
	public function make($src, $dest=null)
	{
		$zip = new ZipArchive;

		if ( !is_writable($dest) ) {
			require_once 'Concentre/Archive/Exception.php';
			throw new Concentre_Archive_Exception(sprintf('Invalid destination file : %s', $dest));
		}

	
		if ($zip->open($dest, ZipArchive::CREATE) === true) {
			foreach ($src as $item) {
				/*
				if ($item->isDir($item)) {
					$this->addItem($zip, realpath(dirname($item)).'/', realpath($item).'/');
				} elseif($item->isFile($item)) {
					$zip->addFile(realpath($item), basename(realpath($item)));
				}
				*/
			}
			
			$zip->close();
			return true;
		}
		
		return false;
	}
	
    /**
     * Extract archive
     *   
     * @param  string $src
     * @param  string $dest
     * @return binary|string|boolean
     */	
	public function extract($src, $dest)
	{
		if (!file_exists($src)) {
			require_once 'Concentre/Archive/Exception.php';
			throw new Concentre_Archive_Exception(sprintf("Source file doesn't exists : %s", $src));
		}

		if ( !file_exists($dest) && !is_dir($dest) && !is_writable($dest) ) {
			require_once 'Concentre/Archive/Exception.php';
			throw new Concentre_Archive_Exception(sprintf("Invalid destination directory : %s", $dest));
		}
		
		$zip = new ZipArchive;
		
		if ($zip->open($src)===true) {
			$zip->extractTo($dest);
			$zip->close();
			return true;
		}
		
		return false;
	}

    /**
     * Add item to archive
     *   
     * @param  string $src
     * @param  string $dest
     * @return binary|string|boolean
     */	
	public function addItem ($zip, $racine, $dir)
	{
		/*
		if (is_dir($dir)) {
			$zip->addEmptyDir(str_replace($racine, '', $dir));
			$lst = scandir($dir);
			array_shift($lst);
			array_shift($lst);
			
			foreach ($lst as $item) {
				$this->addItem($zip, $racine, $dir.$item.(is_dir($dir.$item)?'/':''));
			}
		} elseif (is_file($dir)) {
			$zip->addFile($dir, str_replace($racine, '', $dir));
		}
		*/
	}
	
    /**
     * Get infos
     * 
     * @param  string $src
     * @return object
     */
	public function infos($src)
	{
		if (!file_exists($src) && is_readable($src)) {
			throw new Concentre_Archive_Exception('File not found.');
		}
		
		
		if ($zip = zip_open($src))
		{
			
			$content = array();
			
			while (($zip_entry = zip_read($zip)))
			{
				$path = zip_entry_name($zip_entry);
				if (zip_entry_open($zip, $zip_entry, "r"))
				{
					$entry = new stdClass;
					$entry->Path = $path;
					$entry->Ratio = zip_entry_filesize($zip_entry) ? round(100-zip_entry_compressedsize($zip_entry) / zip_entry_filesize($zip_entry)*100, 1) : false;
					$entry->Size = zip_entry_compressedsize($zip_entry);
					$entry->UnCompSize = zip_entry_filesize($zip_entry);
										
					if ($data) {
						$entry->Data = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
					}
					
					array_push($content, $entry);
					zip_entry_close($zip_entry);
				}
			}
			zip_close($zip);
			return $content;
			
		}

	}	
}
